#ifndef __FAT32_H
#define __FAT32_H
#include "stm32f10x.h"

#define DPT_ADDR     0x1BE
#define RESERVEDSECTORNUM_ADDR    0x0E//保留扇区数，2字节
#define FATSECTORNUM_ADDR    0x24//FAT扇区大小数
#define FATNUM_ADDR 0x10//FAT表个数
#define SECTORSIZE_ADDR  0x0B//扇区字节数
#define CLUSTERSIZE_ADDR 0x0D//每簇扇区数
#define Dir1Size 0x20//一个目录项大小
#define RootDirCluster 2//根目录簇号


typedef enum FAT_ERROR
{
	FAT32_NOTFOUND,
	MBR_NOTFOUND,
	SD_failed,
	FAT_OK,
	FileNotFound,
	scan_over,
	FileFound,
	Notfound,
	File_End,
	FAT_Fulled,
	
}FAT_ERROR;

//目录项结构体
typedef struct FAT32_DirStruct
{
    char FileName[8];//file name
    char ExpandName[3];//extension name
    u8 attribute;//attribute
    u8 SysReserved;//system reserved
    u8 CreateTime_10ms;//the time at 10ms 
    u16 CreateTime;
    u16 CreateDate;
    u16 AccessTime;
    u16 Cluster_H16;//start cluster H16
    u16 ModifyTime;
    u16 ModifyDate;
    u16 Cluster_L16;//start cluster L16
    u32 FileLens;//file lenth in cluster
}FAT32_DirStruct;



//MBR分区信息结构体
typedef struct FAT32_MBR
{
    u8 ParState;//分区状态：活动或者非活动
    u8 FSysType;//文件系统类型
    u32 StartSector;//起始扇区号
    u32 OccupiedSector;//占有扇区
}FAT32_MBR;
//FAT BPB结构，扇区相关信息
typedef struct FAT32_Volume
{
	u8 FATNum;//FAT表数
	u8 ClusterSizeOfSector;//簇的扇区数
	u16 SectorSize;//扇区字节数
	u32 FATSizeOfSector;//一个FAT表扇区数
	u32 FATSector;//表1的扇区号
	u32 Sector_Root;//根目录扇区号
	u32 uesd_dir_root;//根目录已使用目录项
	FAT32_MBR* MBR;//MBR指针
}FAT32_Volume;

//正在打开读取的文件
typedef struct fat32_file
{
		char fname[8];//文件名
    char fext[3];//文件后缀
    u16 pDir_Sector;//当前目录偏移扇区号
		u32 file_dir;//当前扇区目录项
    u32 startCluster;//文件起始簇号
    u32 pCluster;//文件当前簇号
    u32 pSector;//已读取的相对扇区号
    FAT32_Volume* Volume;//卷指针
}fat32_file;

/*
//Fat32正在打开的文件夹目录
typedef struct Fat32_foldering
{
    //通过簇号寻址文件位置
    u32 ClusterBack;//前一目录簇号
    u32 Cluster;//当前目录簇号 
};
*/

FAT_ERROR FAT32_Init(FAT32_MBR* MBR_Info, FAT32_Volume* Volume, fat32_file* File);//FAT32初始化
FAT_ERROR FAT32_MBR_Init(u8* Buffer, FAT32_MBR* MBR_Info);//通过SDIO读取的第一个扇区，获取FAT信息，返回MBR状态。
FAT_ERROR FAT32_Volume_Init(u8* Buffer, FAT32_MBR* MBR, FAT32_Volume* Volume);
FAT_ERROR fat32_findExt(fat32_file* file, const char* extname);//通过后缀名找文件
FAT_ERROR fat32_fread(fat32_file* File, void* Buffer);//通过文件信息读取文件内容，接着读。
FAT_ERROR fat32_fnew(fat32_file* file, const char* fname, FAT32_Volume* volume, u32* fat_buf);//新建文件
FAT_ERROR fat32_fwrite(fat32_file* file, void* buf, u32* fat_buf);//写入文件,FAT表写入缓存
FAT_ERROR fat32_Clusteralloc(fat32_file* file, u32* fat_buf);//分配空闲簇
FAT_ERROR fat32_fclose(fat32_file* file, u32* fat_buf);
void fat32_file_init(fat32_file* file);//初始化file结构体
void FAT32_nextcluster(u8* Buffer, fat32_file* File);//通过对应扇区的FAT值修改File的当前簇号


#define FAT32_GetDirSector(File) ((\
					long long)File->pDir_Sector +\
					File->Volume->Sector_Root+\
					file->Volume->MBR->StartSector)//获取目录当前扇区号
					
	//当前簇FAT扇区
#define FAT32_getFileFATSector(File) (\
					File->pCluster / \
					(File->Volume->SectorSize >> 2) + \
					(long long)File->Volume->FATSector+\
					File->Volume->MBR->StartSector)

//通过File，返回读取的簇的扇区号,根目录扇区号+（当前簇号-根目录簇号）*簇扇区数
#define FAT32_getFileClusterSector(File) (\
					File->Volume->Sector_Root + \
					(long long)(File->pCluster - RootDirCluster)*\
					File->Volume->ClusterSizeOfSector+\
					File->Volume->MBR->StartSector)  


#endif
